﻿using System;
using System.Security.Principal;
using System.Threading;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Security;
using Microsoft.Practices.Unity;
using MongoDB.Bson.Serialization;
using Yamfinder.Data;
using Yamfinder.Service;
using Yamfinder.Web.Controllers;

namespace Yamfinder.Web
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : System.Web.HttpApplication
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
        }

        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });

            routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
            );

        }

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);

            ConfigureUnity();
            SetupControllerFactory();
        }

        protected void Application_AuthenticateRequest(object sender, EventArgs e)
        {
            var cookie = Request.Cookies[FormsAuthentication.FormsCookieName];

            if (cookie != null)
            {
                var ticket = FormsAuthentication.Decrypt(cookie.Value);

                var roles = UnityContainer.Resolve<IUserService>().IsUserAdmin(ticket.Name) ? new[] {"Admin"} : new string[] { };

                Context.User =
                    Thread.CurrentPrincipal = new GenericPrincipal(Context.User.Identity, roles);
            }
        }

        public static IUnityContainer UnityContainer { get; set; }

        private static void ConfigureUnity()
        {
            UnityContainer = new UnityContainer();

            //Register Controllers
            UnityContainer.RegisterType<IController, HomeController>("Home")
                .RegisterType<IController, AccountController>("Account")
                .RegisterType<IController, SearchController>("Search")
                .RegisterType<IController, ImportController>("Import");


            //Register Services
            UnityContainer.RegisterType<ICryptoService, CryptoService>()
                .RegisterType<IUserService, UserService>()
                .RegisterType<IDataTypeService,DataTypeService>()
                .RegisterType<ILexicalService,LexicalService>()
                .RegisterType<IImportService, ImportService>();


            //Register Repositories
            UnityContainer.RegisterType<IUserRepository, UserRepository>()
                .RegisterType<ILexicalRepository, LexicalRepository>()
                .RegisterType<IDataSource, DataSource>()
                .RegisterType<IDataDictonaryRepository, DataDictonaryRepository>()
                .RegisterType<IImportRepository, ImportRepository>();

            //Other
            UnityContainer.RegisterType<ILexicalQuery, LexicalQuery>()
                .RegisterType<LexicalEntrySerialiser>(new ContainerControlledLifetimeManager());

            //Register the custome serialiser
            BsonSerializer.RegisterSerializer(typeof (LexicalEntry), UnityContainer.Resolve<LexicalEntrySerialiser>());
            
        }

        private static void SetupControllerFactory()
        {
            var factory = new UnityControllerFactory(UnityContainer);
            ControllerBuilder.Current.SetControllerFactory(factory);
        }
    }
}